package se.webbzon.boltzmann.minigame;

import java.util.ArrayList;
import java.util.Collection;

import se.webbzon.boltzmann.input.Input;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldcamera.WorldView;

public abstract class Minigame {
	
	// A collection of all the listeners to this minigame
	private final Collection<MinigameListener> listeners;
	
	// Whatever this minigame is running
	public boolean running;
	
	// The world area to return to when the minigame is terminated
	private WorldArea minigame, base;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public Minigame() {
		listeners = new ArrayList<MinigameListener>();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a new listener to the minigame. **/
	public boolean addListener(MinigameListener listener) {
		return listeners.add(listener);
	}
	
	/** Removes a new listener to the minigame. **/
	public boolean removeListener(MinigameListener listener) {
		return listeners.remove(listener);
	}
	
	/** Clears all the listeners in this minigame. **/
	public void clearListeners() {
		listeners.clear();
	}
	
	/** Returns true if the minigame is running. **/
	public final boolean isRunning() {
		return running;
	}
	
	/** Starts the minigame from the provided world by using the
	 * provided view. **/
	public final boolean start(WorldArea world, WorldView view, Input input) {
		if (!running) {
			minigame = load(view,input);
			if (minigame == null) 
				return false;
			else {
				base = world;
				world.gotoWorldArea(minigame);
				onBegin(minigame);
				for (MinigameListener listener : listeners.toArray(new MinigameListener[0]))
					listener.onStart(this);
				running = true;
				return true;
			}
		} else
			return false;
	}
	
	/** Terminates the minigame and returns to the original world. **/
	public final boolean end() {
		if (running) {
			onEnd(minigame);
			for (MinigameListener listener : listeners.toArray(new MinigameListener[0]))
				listener.onEnd(this);
			minigame.gotoWorldArea(base);
			return true;
		} else
			return false;
	}
	
	/*============================================================
	Protected Methods
	============================================================*/
	
	/** Loads the world area of the minigame. If the world could not
	 * be loaded then null is returned. **/
	protected abstract WorldArea load(WorldView view, Input input);
	
	/** This method is invoked when the minigame is about to start. **/
	protected abstract void onBegin(WorldArea world);
	
	/** This method is invoked when the minigame is about to end. **/
	protected abstract void onEnd(WorldArea world);

}
